package com.koron.rating.rating;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.koron.bean.base.Response;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.bean.workflow.RedirectQuery;
import com.koron.bean.workflow.WorkflowController;
import com.koron.common.core.business.workflow.templates.WorkFlowHandler;
import com.koron.common.core.business.workflow.util.TextUtil;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.CommonUtils;
import com.koron.common.core.util.StringUtils;
import com.koron.rating.aop.Idempotent;
import com.koron.rating.enums.RatingCodeEnum;
import com.koron.rating.enums.RatingWorkFlowStatusEnum;
import com.koron.rating.enums.UnitCensusTypeEnum;
import com.koron.rating.rating.bean.*;
import com.koron.rating.rating.mapper.RatingCompanyMapper;
import com.koron.rating.rating.mapper.RatingOrderMapper;
import com.koron.rating.rating.mapper.RatingUnitHistoryMapper;
import com.koron.rating.units.RatingUnits;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author: rocky
 * @Date: 2022/1/11 9:46
 */
@Slf4j
@RequestMapping("/rating")
@RestController
@Api(tags = "设备评级-设备评级单")
public class RatingController implements WorkflowController {

    private String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    private EamUser getEamUser() {
        return ThreadLocalContext.get();
    }

    @Autowired
    private WorkFlowHandler workflowhandler;

    @Autowired
    private RatingService ratingservice;

    @PostMapping("queryList")
    @ApiOperation(value = "列表")
    public Response<PageInfo> queryList(@RequestBody RatingOrderDto querbean) {
        List<RatingOrderDto> list = ADOConnection.runTask(getCurrDs(), factory -> {
            PageHelper.startPage(querbean.getPage(), querbean.getPageSize(), querbean.getOrderBy());
            querbean.setDeptlist(CommonUtils.getPower(getEamUser()));
            querbean.setCreateBy(getEamUser().getAccount());
            List<RatingOrderDto> tem = factory.getMapper(RatingOrderMapper.class).queryByAll(querbean);
            return tem;
        }, List.class);
        return Response.ok(new PageInfo<>(list));
    }

    @PostMapping("saveOrUpdate")
    @ApiOperation(value = "保存")
    public Response<String> saveOrUpdate(@RequestBody RatingOrderVo vo) {
        RatingOrderBean bean = Convert.convert(RatingOrderBean.class, vo);
        List<RatingCompanyBean> det = vo.getDet();
        String id = ADOConnection.runTask(getCurrDs(), factory -> {
            RatingOrderMapper mapper = factory.getMapper(RatingOrderMapper.class);
            RatingCompanyMapper detmapper = factory.getMapper(RatingCompanyMapper.class);

            if (StringUtils.isBlank(vo.getId())) {
                String temid = CodeTools.getCode32();
                String billNo = RatingUnits.getRatingCode(RatingCodeEnum.PJ);
                bean.setId(temid);
                bean.setUnitid(getEamUser().getDeptId());
                bean.setUnitname(getEamUser().getDeptName());
                bean.setBillNo(billNo);
                mapper.insertSelective(bean);

                det.stream().forEach(d -> {
                    d.setId(CodeTools.getCode32());
                    d.setOrderId(temid);
                });
            } else {
                detmapper.deleteByOrderId(vo.getId());//删除评级人、评级单位
                mapper.updateByPrimaryKeySelective(bean);
                det.stream().forEach(d -> {
                    d.setId(CodeTools.getCode32());
                    d.setOrderId(bean.getId());
                });
            }
            detmapper.batchInsert(det);//评级人、评级单位 入库
            return bean.getId();
        }, String.class);
        return Response.ok(id);
    }

    @Idempotent(key = "id", topicMessage = "同步评级单元正在执行中，请勿重复操作！")
    @GetMapping("synUnit")
    @ApiOperation(value = "同步最新单元划分")
    public Response<String> synUnit(@RequestParam("id") String id) {
        ADOConnection.runTask(getCurrDs(), ratingservice, "synUnit", List.class, id);
        return Response.ok("SUCCESS");
    }

    @GetMapping("details")
    @ApiOperation(value = "详情")
    public Response<RatingOrderBean> details(@RequestParam("id") String id) {
        RatingOrderBean result = ADOConnection.runTask(getCurrDs(), factory -> {
            RatingOrderBean tem = factory.getMapper(RatingOrderMapper.class).selectByPrimaryKey(id);
            List<RatingCompanyBean> det = factory.getMapper(RatingCompanyMapper.class).queryByOrderId(id);
            tem.setDet(det);
            return tem;
        }, RatingOrderBean.class);
        return Response.ok(result);
    }


    @GetMapping("rating")
    @ApiOperation(value = "评级")
    public Response<String> rating(@RequestParam("id") String id, @RequestParam("beforGrade") Integer beforGrade, @RequestParam("nowGrade") Integer nowGrade) {
        ADOConnection.runTask(getCurrDs(), factory -> {
            factory.getMapper(RatingUnitHistoryMapper.class).updateBeforGradeAndNowGradeById(beforGrade, nowGrade, id);
            return true;
        }, Boolean.class);
        return Response.ok("SUCCESS");
    }

    @GetMapping("gradeRemarks")
    @ApiOperation(value = "评级留言")
    public Response<String> gradeRemarks(@RequestParam("id") String id, @RequestParam("gradeRemarks") String gradeRemarks) {
        ADOConnection.runTask(getCurrDs(), factory -> {
            factory.getMapper(RatingUnitHistoryMapper.class).updateGradeRemarksById(gradeRemarks, id);
            return true;
        }, Boolean.class);
        return Response.ok("SUCCESS");
    }

    @GetMapping("ratingDelete")
    @ApiOperation(value = "评级单删除")
    public Response<String> ratingDelete(@RequestParam("id") String id) {
        String account = ThreadLocalContext.get().getAccount();
        String name = ThreadLocalContext.get().getName();

        ADOConnection.runTask(getCurrDs(), factory -> {
            RatingOrderBean ratingOrderBean = new RatingOrderBean();
            ratingOrderBean.setId(id);
            ratingOrderBean.setUpdateTime(new Date());
            ratingOrderBean.setUpdateBy(account);
            ratingOrderBean.setUpdateByName(name);
            factory.getMapper(RatingOrderMapper.class).updateById(ratingOrderBean);

            factory.getMapper(RatingCompanyMapper.class).deleteByOrderId(id);
            //factory.getMapper(RatingUnitHistoryMapper.class).deleteByOrderId(id);

            RatingUnitHistoryBean unitHistoryBean = new RatingUnitHistoryBean();
            unitHistoryBean.setOrderId(id);
            unitHistoryBean.setDeleteFlag(1);

            factory.getMapper(RatingUnitHistoryMapper.class).updateByOrderId(unitHistoryBean);

            boolean delete = workflowhandler.delete(id);//流程记录删除
            Assert.isTrue(delete, "工作流删除异常");
            return true;
        }, Boolean.class);
        return Response.ok("SUCCESS");
    }

// ===================================================================================================================
// 单元树


    @GetMapping("/getInitTreeLazy")
    @ApiOperation(value = "查询设备单元树形结构（初始进入）")
    public Response<List<RatingUnitHistoryBean>> getInitTreeLazy(String orderId) {
        Assert.isFalse(StringUtils.isEmpty(orderId), "评级单id不能为空");
        return ADOConnection.runTask(getCurrDs(), ratingservice, "getInitTreeLazy", Response.class, orderId);
    }

    @GetMapping("/getTreeLazy")
    @ApiOperation(value = "查询设备单元树形结构（懒加载）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "评级单id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "parentId", value = "单元 dataSources", required = true, dataType = "String")})
    public Response<List<RatingUnitHistoryBean>> getTreeLazy(String orderId, String parentId) {
        Assert.isFalse(StringUtils.isEmpty(parentId), "父节点不能为空");
        return ADOConnection.runTask(getCurrDs(), ratingservice, "getTreeLazy", Response.class, orderId, parentId);
    }

    @GetMapping("/searchByNameOntree")
    @ApiOperation(value = "根据设单元称模糊查询(树 只查单位、单元)")
    public Response<List<RatingUnitHistoryBean>> searchByNameOntree(String orderId, String name) {
        return ADOConnection.runTask(getCurrDs(), ratingservice, "searchByNameOntree", Response.class, orderId, name);
    }

    @GetMapping("/searchByNameOnRating")
    @ApiOperation(value = "根据设单元称模糊查询(树 只查设备、部件)")
    public Response<List<RatingUnitHistoryBean>> searchByName(RatingUnitHistoryDto dto) {
        return ADOConnection.runTask(getCurrDs(), ratingservice, "searchByNameOnRating", Response.class, dto);
    }

    @GetMapping("/getParentIds")
    @ApiOperation(value = "获取某个节点的所有父节点")
    public Response<List<String>> getParentIds(String orderId, String dataSources) {
        return ADOConnection.runTask(getCurrDs(), ratingservice, "getParentIds", Response.class, orderId, dataSources);
    }

    @GetMapping("/getByDataSources")
    @ApiOperation(value = "查询单个单元")
    public Response<RatingUnitHistoryBean> getByDataSources(String dataSources) {
        return ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), ratingservice, "getByDataSources", Response.class, dataSources);
    }


// ===================================================================================================================

    @GetMapping("/getThisOrderPic")
    @ApiOperation(value = "饼图  本次、上次评级分布  NOW:本次、BEFOR:上次")
    public Response getThisOrderPic(String orderId, String type) {
        List<RatingGroupCountVo> list = ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), ratingservice, "getThisOrderPic", List.class, orderId, type);
        return Response.ok(list);
    }

    @PostMapping("/compareReport")
    @ApiOperation(value = "评级情况汇总表")
    public Response compareReport(@RequestBody RatringComparisonDto dto) {
        List<RatringComparisonVo> list = new ArrayList<>();
        //本年
        if (dto.getType().equals(UnitCensusTypeEnum.NOW.getLabel())) {
            list = ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), ratingservice, "compareReport", List.class, dto);
        }
        //往年
        if (dto.getType().equals(UnitCensusTypeEnum.BEFOR.getLabel())) {
            String orderId = ratingservice.getberforOrderId(dto.getOrderId());
            //上次评级单
            dto.setOrderId(orderId);//找到就替换 没找到放一个空串，让里面识别
            list = ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), ratingservice, "compareReport", List.class, dto);
        }

        return Response.ok(list);
    }

    @PostMapping("/nowRatingGradeCount")
    @ApiOperation(value = "本次评级等级统计")
    public Response nowRatingGradeCount(@RequestParam("orderId") String orderId, @RequestParam(value = "grade", required = false) Integer grade, @RequestParam("iscore") Boolean iscore, String companyId ) {
        if(grade == 0){
            grade = null;
        }
        List<RatingGradeCensusVo> list = ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), ratingservice, "nowRatingGradeCount", List.class, companyId, orderId, grade, iscore);
        return Response.ok(list);
    }


    @GetMapping("/iteration")
    @ApiOperation(value = "新增、减少的三、四类设备清单 type: ADD:新增、REMOVE:减少 ")
    public Response<List<RatringNewOldVo>> iteration(@RequestParam("orderId") String orderId, @RequestParam("type") String type) {
        List<RatringNewOldVo> list = new ArrayList<>();

        //查询新增三四类设备 变坏
        if (type.equals(UnitCensusTypeEnum.ADD.getLabel())) {
            list = ADOConnection.runTask(getCurrDs(), factory -> {
                return factory.getMapper(RatingUnitHistoryMapper.class).gradeComparBad(orderId);
            }, List.class);
        }

        //查询减少三四类设备 变好
        if (type.equals(UnitCensusTypeEnum.REMOVE.getLabel())) {
            list = ADOConnection.runTask(getCurrDs(), factory -> {
                return factory.getMapper(RatingUnitHistoryMapper.class).gradeComparGood(orderId);
            }, List.class);
        }

        return Response.ok(list);
    }

    @ApiOperation("统计设备级和部件级")
    @GetMapping("/staCount")
    public Response<Map> staCount(@RequestParam("orderId") String orderId, @RequestParam("equipmentIds") ArrayList<String> equipmentIds){

        return Response.succ(ADOConnection.runTask(getCurrDs(), ratingservice,"staEquipCount", Map.class, orderId, equipmentIds));
    }


    @Override
    @ApiOperation("修改业务状态, 非前端接口")
    public Response<Object> updateState(@RequestBody RedirectQuery redirectQuery) {
        log.info("工作流更新： {}", JSON.toJSONString(redirectQuery));
        Map<String, String> infoMap = TextUtil.toMapFromString(redirectQuery.getFormVariables());
        log.info("流程状态：" + redirectQuery.getCurNodeCode());
        log.info(String.valueOf(redirectQuery));


        // 驳回到填写
        if (redirectQuery.getCurNodeCode().equals("draft-WRITE")) {
            ADOConnection.runTask(getCurrDs(), factory -> {
                factory.getMapper(RatingOrderMapper.class).updateEndStatus(RatingWorkFlowStatusEnum.DRAFT.getLabel(), null, null, infoMap.get("id"));
                return true;
            }, Boolean.class);
            return Response.success();
        }
        ADOConnection.runTask(getCurrDs(), factory -> {
            factory.getMapper(RatingOrderMapper.class).updateEndStatus(RatingWorkFlowStatusEnum.WAIT_REVIEW.getLabel(), null, null, infoMap.get("id"));
            return true;
        }, Boolean.class);
        return Response.success();
    }

    @Override
    @ApiOperation("结束时的修改方法, 非前端接口")
    public Response<Object> updateEnd(@RequestBody RedirectQuery redirectQuery) {
        log.info("工作流完结 ： {}", JSON.toJSONString(redirectQuery));
        Map<String, String> infoMap = TextUtil.toMapFromString(redirectQuery.getFormVariables());
        //流程结束-更新评级单时间、年份、状态
        ADOConnection.runTask(getCurrDs(), factory -> {
            factory.getMapper(RatingOrderMapper.class).updateEndStatus(RatingWorkFlowStatusEnum.APPROVED.getLabel(), new Date(), DateUtil.year(new Date()), infoMap.get("id"));
            return true;
        }, Boolean.class);
        return Response.success();
    }

    @Override
    @ApiOperation("作废时的修改方法, 非前端接口")
    public Response<Object> updateCancel(@RequestBody RedirectQuery redirectQuery) {
        log.info("updateCancel = {}", JSON.toJSONString(redirectQuery));
        return Response.success();
    }


}
